import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Scroll extends JFrame {

	private JScrollBar scroll;
	private JButton bStart;
	private JButton bStop;
	private JPanel panel;
	private final JTextArea area;

	public Scroll() {
		scroll = new JScrollBar();
		bStart = new JButton("Start");
		bStart.setBackground(Color.WHITE);
		bStop = new JButton("Stop");
		bStop.setBackground(Color.WHITE);
		bStop.setEnabled(false);
		panel = new JPanel();
		panel.setLayout(new BorderLayout());
		area = new JTextArea();
		panel.add(area, BorderLayout.CENTER);
		area.setPreferredSize(new Dimension(400, 600));
		area.setBackground(Color.WHITE);

		JPanel panelSouth = new JPanel();
		panelSouth.setBackground(Color.BLACK);
		panelSouth.add(bStart);
		panelSouth.add(bStop);
		panel.add(panelSouth, BorderLayout.SOUTH);

		panel.add(scroll, BorderLayout.EAST);

		getContentPane().add(panel);

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(new Dimension(400, 600));
		this.setLocationRelativeTo(null);
	}

	private void init() {
		Task task = new Task(5000);
		Thread t = new Thread(task);
		manageBStart(t);
		manageBStop(t);
		area.append("initialization ... Ok");
	}

	private void doStart(Thread t) {
		while (!t.isAlive()) {
			System.out.println("Thread is not alive");
			area.append("Thread is about to be run");
			try {
				if (!SwingUtilities.isEventDispatchThread()) {
					t.start();
					SwingUtilities.invokeAndWait(new Runnable() {

						@Override
						public void run() {
							bStart.setEnabled(false);
							bStop.setEnabled(true);
						}
					});
				} else {
					bStart.setEnabled(false);
					bStop.setEnabled(true);
				}
			} catch (InvocationTargetException | InterruptedException e) {
				e.printStackTrace();
			}
		} 
		this.notify();
	}

	private void doStop(Thread t) {
		if (t.isAlive()) {
			try {
				if (!SwingUtilities.isEventDispatchThread()) {
					synchronized (this) {
						System.out.println("stop");
						bStop.setEnabled(false);
						bStart.setEnabled(true);
						this.wait();
					}
				} else {
					System.out.println("Need to wait...");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private class Task implements Runnable {

		private final int MAX;
		private String currentResult = "";

		public Task(int max) {
			MAX = max;
		}

		@Override
		public void run() {
			getString();
		}

		private void getString() {
			int i = 0;
			while (true) {
				try {
					i++;
					currentResult = "" + i;
					SwingUtilities.invokeLater(new Runnable() {

						@Override
						public void run() {
							area.append(currentResult + "\n");
							System.out.println(currentResult);
						}
					});
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void manageBStart(final Thread t) {
		bStart.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("start");
				doStart(t);
			}
		});
	}

	private void manageBStop(final Thread t) {
		bStop.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				doStop(t);
			}
		});
	}

	private void updateArea() {
		SwingWorker<String, String> sw = new SwingWorker<String, String>() {

			@Override
			protected String doInBackground() throws Exception {
				return null;
			}
		};
		sw.execute();
	}

	public static void main(String[] args) {
		Scroll scroll = new Scroll();
		scroll.init();
		scroll.setVisible(true);
	}
}
